/**
 * @param {string} s1
 * @param {string} s2
 * @return {boolean}
 */
var checkInclusion = function (s1, s2) {
    let len1 = s1.length
    let len2 = s2.length
    let arr1 = new Array(128).fill(0)
    let arr2 = new Array(128).fill(0)
    for (let i = 0; i < len1; i++) {
        arr1[s1.charCodeAt(i)] += 1
        arr2[s2.charCodeAt(i)] += 1
    }

    let k = 0
    // 右边界不超过 s2的最大值
    while (k + len1 - 1 < len2) {
        let tempI = k
        let code = s2.charCodeAt(tempI)

        // 对 arr1和arr2 遍历进行比较
        while (tempI < k + len1 && arr1[code] && arr1[code] === arr2[code]) {
            tempI++
            code = s2.charCodeAt(tempI)
        }

        //如果都相同,则表示s1的某个排列时s2的子串
        if (tempI === k + len1) {
            return true
        }
        // 不包含,则将窗口向右滑动，并更新arr2种相应字符的统计信息
        //左边向右移动一个
        arr2[s2.charCodeAt(k)] -= 1
        // 右边向右移动一个
        arr2[s2.charCodeAt(++k + len1 - 1)] += 1
    }
    return false
};
console.log(checkInclusion('abc', "cccccbabbbaaaa"))

//================v1要点总结===============
/**
 * 1. 不要求子串顺序，那尝试通过统计字符个数来解决
 * 2. 注意右边界的取值，假设 窗口长度为 3， 左边界为0，右边界则为 2，此时由左边界0得到右边界右移一位的值3 ，则 2 + 1 = (0 + 3 - 1) + 1 = 0 + 3 = k + len1
 * 3. 缺点：每次都要去遍历所有字符的个数进行比较
 */